package com.myk.game.gobangchess.rooms;

import com.myk.game.gobangchess.constants.BoardStyleData;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.Room;
import com.myk.game.gobangchess.signs.AroundSign;

import java.util.ArrayList;
import java.util.List;

/**
 * 空灵五子棋
 */
public class AiryGoBangRoom extends Room{
    public AiryGoBangRoom(String roomName) {
        super(roomName, "\t\t日出对五子棋的探索之一。","空灵五子棋", BoardStyleData.getGoBangStyle(17,17), true, true);
    }
    private int[] firstConsecutive;//(1竖直，2右上，3水平，4右下)+首尾
    private int[][] blackScoreLocation;
    private int[][] whiteScoreLocation;

    @Override
    public String getRuleText() {
        return  "黑先白后，交替下棋。\n" +
                "形成“连五”时，其周围空格数为N，得10*N分。\n" +
                "五子以上的连珠统一视作“连五”，不重复得分。\n" +
                "开局白棋加15分。先得100分者胜。\n" +
                "出现两条及以上“连五”时，得分高者胜利。" ;

    }
    @Override
    protected void onStartPrepare() {
        whiteScore = 15;
        blackScore = 0;
        firstConsecutive=new int[]{0,-1,-1,-1,-1};
        blackScoreLocation=new int[][] {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}};
        whiteScoreLocation =new int[][] {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}};
        noticeBlackMove();
    }

    @Override
    public void resetGrids() {
        super.resetGrids();
        whiteScore = 0;
        blackScore = 0;
        firstConsecutive=new int[]{0,-1,-1,-1,-1};
        blackScoreLocation=new int[][] {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}};
        whiteScoreLocation =new int[][] {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}};
    }

    @Override
    public void doRule(int row, int col, int value) {
        if (curGrids[row][col] == 0) { //只能落在空位置
            signList.clear();
            List<Integer> ids = new ArrayList<>();
            ids.add(getIndex(row,col));
            signList.add(new AroundSign(ids,"#00000000","#6600FF00",1.2f));
            curGrids[row][col] = value; //实际落子
            stepAdd(); //步数统计加增加
            int flag = checkFormation(row,col,value);
            if (flag==0) {
                if (value == 1) {
                    noticeWhiteMove();
                } else {
                    noticeBlackMove();
                }
                return ;
            }else if (flag==2){
                if (value == 1) {
                    doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "执黑棋，战胜" + player_white.getNickNameOrTemp());
                } else {
                    doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "执白棋，战胜" + player_black.getNickNameOrTemp());
                }
                return;
            }else if (flag==1){
                if (blackScore>whiteScore) {
                    doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "执黑棋，战胜" + player_white.getNickNameOrTemp());
                } else {
                    doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "执白棋，战胜" + player_black.getNickNameOrTemp());
                }
                return;
            }
            if (value == 1) {
                noticeWhiteMove();
            } else {
                noticeBlackMove();
            }
        }
    }

    //获取成5的次数
    private int checkFormation(int row ,int col,int value) {//返回0失败，1第一次，2两分同人结束，3不同人比分
        final int rows = curGrids.length-1;
        final int cols = curGrids[0].length-1;

        int formationCount = 1;
        int consecutiveNumber=5;
        //左下到右上
        int left = Math.min(Math.min(rows-row,col),consecutiveNumber-1);
        int right = Math.min(Math.min(row,cols-col),consecutiveNumber-1);
        int min=0;//统计left数量，使得已五连不参与五连
        int max=0;
        for (int i = 1; i <= left; i++) {
            if (firstConsecutive[0]==2&&((row+i==firstConsecutive[1]&&col-i==firstConsecutive[2])||(row+i==firstConsecutive[3]&&col-i==firstConsecutive[4]))){
                break;
            }
            if (curGrids[row+i][col-i] == value){
                formationCount++;
                min++;
            }else{
                break;
            }
        }
        for (int i = 1; i <= right; i++) {
            if (firstConsecutive[0]==2&&((row-i==firstConsecutive[1]&&col+i==firstConsecutive[2])||(row-i==firstConsecutive[3]&&col+i==firstConsecutive[4]))){
                break;
            }
            if (curGrids[row-i][col+i] == value){
                formationCount++;
                max++;
            }else{
                break;
            }
        }
        if (formationCount >= consecutiveNumber) {
            getAddScore(row,col);
            if (firstConsecutive[0]==0){ //不能直接用分数，考虑五连不得分
                firstConsecutive= new int[] {2,row+min,col-min,row-max,col+max};
            }else{
                return 1;
            }

        }
        formationCount = 1;

        //水平方向
        left = Math.min(col,consecutiveNumber-1); //左侧（竖直时定义为上）
        right = Math.min(cols-col,consecutiveNumber-1); //右侧(竖直时定义为下)
        min = 0;
        max = 0;
        for (int i = 1;i<=left;i++) {
            if (firstConsecutive[0]==3 &&((row==firstConsecutive[1]&&col-i==firstConsecutive[2])||(row==firstConsecutive[3]&&col-i==firstConsecutive[4]))){
                break;
            }
            if (curGrids[row][col-i] == value) {
                formationCount++;
                min++;
            }else{
                break;
            }
        }
        for (int i = 1;i<=right;i++){
            if (firstConsecutive[0]==3&&((row==firstConsecutive[1]&&col+i==firstConsecutive[2])||(row==firstConsecutive[3]&&col+i==firstConsecutive[4]))){
                break;
            }
            if (curGrids[row][col+i] == value){
                formationCount++;
                max++;
            }else{
                break;
            }
        }

        if (formationCount >= consecutiveNumber) {
            getAddScore(row,col);
            if (firstConsecutive[0]==0) {
                firstConsecutive = new int[]{3, row , col - min, row , col + max};
            }else{
                return 1;
            }

        }
        formationCount = 1;

        //左上到右下
        left = Math.min(Math.min(row,col),consecutiveNumber-1);
        right = Math.min(Math.min(rows-row,cols-col),consecutiveNumber-1);
        min = 0;
        max = 0;
        for (int i = 1;i<=left;i++){
            if (firstConsecutive[0]==4&&((row-i==firstConsecutive[1]&&col-i==firstConsecutive[2])||(row-i==firstConsecutive[3]&&col-i==firstConsecutive[4]))){
                break;
            }
            if (curGrids[row-i][col-i] == value){
                formationCount++;
                min++;
            }else{
                break;
            }
        }
        for (int i = 1;i<=right;i++){
            if (firstConsecutive[0]==4&&((row+i==firstConsecutive[1]&&col+i==firstConsecutive[2])||(row+i==firstConsecutive[3]&&col+i==firstConsecutive[4]))){
                break;
            }
            if (curGrids[row+i][col+i] == value){
                formationCount++;
                max++;
            }else{
                break;
            }
        }
        if (formationCount >= consecutiveNumber) {
            getAddScore(row,col);
            if (firstConsecutive[0]==0) {
                firstConsecutive = new int[]{4, row-min , col - min, row + max , col + max};
            }else{
                return 1;
            }

        }
        formationCount = 1;

        //竖直
        left = Math.min(row,consecutiveNumber-1);
        right = Math.min(rows-row,consecutiveNumber-1);
        min = 0;
        max = 0;
        for (int i = 1;i<=left;i++) {
            if (firstConsecutive[0]==1&&((row-i==firstConsecutive[1]&&col==firstConsecutive[2])||(row-i==firstConsecutive[3]&&col==firstConsecutive[4]))){
                break;
            }
            if (curGrids[row-i][col] == value){
                formationCount++;
                min++;
            }else{
                break;
            }
        }
        for (int i = 1;i<=right;i++){
            if (firstConsecutive[0]==1&&((row+i==firstConsecutive[1]&&col==firstConsecutive[2])||(row+i==firstConsecutive[3]&&col==firstConsecutive[4]))){
                break;
            }
            if (curGrids[row+i][col] == value){
                formationCount++;
                max++;
            }else{
                break;
            }
        }
        if (formationCount >= consecutiveNumber) {
            getAddScore(row,col);
            if (firstConsecutive[0]==0) {
                firstConsecutive = new int[]{1, row-min , col , row + max , col };
            }else{
                return 1;
            }

        }
        return 0;
    }
    private int getAddScore(int row,int col){//仅得分返回0，满10分1
        int mayAddscore=0;
        int[][] direction;
        int flag2 = 0;//标记
        int value =curGrids[row][col];
        final int rows = curGrids.length-1;
        final int cols = curGrids[0].length-1;
        final int consecutiveNumber = 5;
        int formationCount = 1;
        int [][] temLocation = new int[40][2];//40为最大可能得分（9颗子）
        //左下到右上
        int left = Math.min(Math.min(rows-row,col),consecutiveNumber-1);
        int right = Math.min(Math.min(row,cols-col),consecutiveNumber-1);
        direction=new int[][] {{1,-1},{0,-1},{-1,-1},{1,0},{1,1}};
        for (int i = 1; i <= left; i++) {
            if (curGrids[row+i][col-i] == value){
                formationCount++;
                for (int j =0;j<5;j++){
                    if (0<=row+i+direction[j][0]&&row+i+direction[j][0]<17&&0<=col-i+direction[j][1]&&col-i+direction[j][1]<17&&curGrids[row+i+direction[j][0]][col-i+direction[j][1]]==0){
                        temLocation[mayAddscore]=new int[] {row+i+direction[j][0],col-i+direction[j][1]};
                        mayAddscore++;
                    }
                }
            }else{
                break;
            }
        }
        direction=new int[][] {{-1,1},{-1,-1},{-1,0},{0,1},{1,1}};
        for (int i = 1; i <= right; i++) {
            if (curGrids[row-i][col+i] == value){
                formationCount++;
                for (int j =0;j<5;j++){
                    if (0<=row-i+direction[j][0]&&row-i+direction[j][0]<17&&0<=col+i+direction[j][1]&&col+i+direction[j][1]<17&&curGrids[row-i+direction[j][0]][col+i+direction[j][1]]==0){
                        temLocation[mayAddscore]=new int[] {row-i+direction[j][0],col+i+direction[j][1]};
                        mayAddscore++;
                    }
                }
            }else{
                break;
            }
        }
        if (formationCount >= 5) {

            if (value==1){
                for (int i=0;i<mayAddscore;i++){
                    for (int j=0;j<blackScore/10;j++){
                        if (blackScoreLocation[j][0]==temLocation[i][0] && blackScoreLocation[j][1]==temLocation[i][1]){
                            flag2=1;
                            System.out.println(113);//for test
                            break;
                        }
                    }
                    if (flag2==1){
                        flag2=0;
                        continue;
                    }
                    blackScoreLocation[blackScore/10][0]=temLocation[i][0];
                    blackScoreLocation[blackScore/10][1]=temLocation[i][1];
                    blackScore+=10;
                    if (blackScore==100){
                        doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "执黑棋，战胜" + player_white.getNickNameOrTemp());
                        return 1;
                    }
                }

            }
            else{
                for (int i=0;i<mayAddscore;i++){
                    for (int j=0;j<(whiteScore-5)/10;j++){
                        if (whiteScoreLocation[j][0]==temLocation[i][0] && whiteScoreLocation[j][1]==temLocation[i][1]){
                            flag2=1;
                            break;
                        }
                    }
                    if (flag2==1){
                        flag2=0;
                        continue;
                    }
                    whiteScoreLocation[(whiteScore-5)/10][0]=temLocation[i][0];
                    whiteScoreLocation[(whiteScore-5)/10][1]=temLocation[i][1];
                    whiteScore+=10;
                    if (whiteScore>=100){
                        doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "执白棋，战胜" + player_black.getNickNameOrTemp());
                        return 1;
                    }
                }
            }

        }
        formationCount = 1;
        mayAddscore=0;
        temLocation = new int[40][2];

        //水平方向
        left = Math.min(col,consecutiveNumber-1); //左侧（竖直时定义为上）
        right = Math.min(cols-col,consecutiveNumber-1); //右侧(竖直时定义为下)
        direction = new int[][] {{-1,-1},{0,-1},{1,-1}};
        for (int i = 1;i<=left;i++) {
            if (curGrids[row][col-i] == value) {
                formationCount++;
                for (int j =0;j<3;j++){
                    if (0<=row+direction[j][0]&&row+direction[j][0]<17&&0<=col-i+direction[j][1]&&col-i+direction[j][1]<17&&curGrids[row+direction[j][0]][col-i+direction[j][1]]==0){
                        temLocation[mayAddscore]=new int[] {row+direction[j][0],col-i+direction[j][1]};
                        mayAddscore+=1;
                    }
                }
            }else{
                break;
            }
        }
        direction = new int[][] {{-1,1},{0,1},{1,1}};
        for (int i = 1;i<=right;i++){
            if (curGrids[row][col+i] == value){
                formationCount++;
                for (int j =0;j<3;j++){
                    if (0<=row+direction[j][0]&&row+direction[j][0]<17&&0<=col+i+direction[j][1]&&col+i+direction[j][1]<17&&curGrids[row+direction[j][0]][col+i+direction[j][1]]==0){
                        temLocation[mayAddscore]=new int[] {row+direction[j][0],col-i+direction[j][1]};
                        mayAddscore+=1;
                    }
                }
            }else{
                break;
            }
        }
        if (formationCount >= consecutiveNumber) {

            if (value==1){
                for (int i=0;i<mayAddscore;i++){
                    for (int j=0;j<blackScore/10;j++){
                        if (blackScoreLocation[j][0]==temLocation[i][0] && blackScoreLocation[j][1]==temLocation[i][1]){
                            flag2=1;
                            break;
                        }
                    }
                    if (flag2==1){
                        flag2=0;
                        continue;
                    }
                    blackScoreLocation[blackScore/10][0]=temLocation[i][0];
                    blackScoreLocation[blackScore/10][1]=temLocation[i][1];
                    blackScore+=10;
                    if (blackScore==100){
                        doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "执黑棋，战胜" + player_white.getNickNameOrTemp());
                        return 1;
                    }
                }

            }
            else{
                for (int i=0;i<mayAddscore;i++){
                    for (int j=0;j<(whiteScore-5)/10;j++){
                        if (whiteScoreLocation[j][0]==temLocation[i][0] && whiteScoreLocation[j][1]==temLocation[i][1]){
                            flag2=1;
                            break;
                        }
                    }
                    if (flag2==1){
                        flag2=0;
                        continue;
                    }
                    whiteScoreLocation[(whiteScore-5)/10][0]=temLocation[i][0];
                    whiteScoreLocation[(whiteScore-5)/10][1]=temLocation[i][1];
                    whiteScore+=10;
                    if (whiteScore>=100){
                        doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "执白棋，战胜" + player_black.getNickNameOrTemp());
                        return 1;
                    }
                }
            }
        }
        formationCount = 1;
        mayAddscore=0;
        temLocation = new int[40][2];


        //左上到右下
        left = Math.min(Math.min(row,col),consecutiveNumber-1);
        right = Math.min(Math.min(rows-row,cols-col),consecutiveNumber-1);
        direction = new int[][] {{-1,-1},{0,-1},{1,-1},{-1,0},{-1,1}};
        for (int i = 1;i<=left;i++){
            if (curGrids[row-i][col-i] == value){
                formationCount++;
                for (int j =0;j<5;j++){
                    if (0<=row-i+direction[j][0]&&row-i+direction[j][0]<17&&0<=col-i+direction[j][1]&&col-i+direction[j][1]<17&&curGrids[row-i+direction[j][0]][col-i+direction[j][1]]==0){
                        temLocation[mayAddscore]=new int[] {row-i+direction[j][0],col-i+direction[j][1]};
                        mayAddscore+=1;
                    }
                }
            }else{
                break;
            }
        }
        direction = new int[][] {{1,1},{0,1},{-1,1},{1,0},{1,-1}};
        for (int i = 1;i<=right;i++){
            if (curGrids[row+i][col+i] == value){
                formationCount++;
                for (int j =0;j<5;j++){
                    if (0<=row+i+direction[j][0]&&row+i+direction[j][0]<17&&0<=col+i+direction[j][1]&&col+i+direction[j][1]<17&&curGrids[row+i+direction[j][0]][col+i+direction[j][1]]==0){
                        temLocation[mayAddscore]=new int[] {row+i+direction[j][0],col+i+direction[j][1]};
                        mayAddscore+=1;
                    }
                }
            }else{
                break;
            }
        }
        if (formationCount >= consecutiveNumber) {
            if (value==1){
                for (int i=0;i<mayAddscore;i++){
                    for (int j=0;j<blackScore/10;j++){
                        if (blackScoreLocation[j][0]==temLocation[i][0] && blackScoreLocation[j][1]==temLocation[i][1]){
                            flag2=1;
                            break;
                        }
                    }
                    if (flag2==1){
                        flag2=0;
                        continue;
                    }
                    blackScoreLocation[blackScore/10][0]=temLocation[i][0];
                    blackScoreLocation[blackScore/10][1]=temLocation[i][1];
                    blackScore+=10;
                    if (blackScore==100){
                        doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "执黑棋，战胜" + player_white.getNickNameOrTemp());
                        return 1;
                    }
                }
            }
            else{
                for (int i=0;i<mayAddscore;i++){
                    for (int j=0;j<(whiteScore-5)/10;j++){
                        if (whiteScoreLocation[j][0]==temLocation[i][0] && whiteScoreLocation[j][1]==temLocation[i][1]){
                            flag2=1;
                            break;
                        }
                    }
                    if (flag2==1){
                        flag2=0;
                        continue;
                    }
                    whiteScoreLocation[(whiteScore-5)/10][0]=temLocation[i][0];
                    whiteScoreLocation[(whiteScore-5)/10][1]=temLocation[i][1];
                    whiteScore+=10;
                    if (whiteScore>=100){
                        doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "执白棋，战胜" + player_black.getNickNameOrTemp());
                        return 1;
                    }
                }
            }
        }
        formationCount = 1;
        mayAddscore=0;
        temLocation = new int[40][2];

        //竖直
        left = Math.min(row,consecutiveNumber-1);
        right = Math.min(rows-row,consecutiveNumber-1);
        direction = new int[][] {{-1,-1},{-1,0},{-1,1}};
        for (int i = 1;i<=left;i++) {
            if (curGrids[row-i][col] == value){
                formationCount++;
                for (int j =0;j<3;j++){
                    if (0<=row-i+direction[j][0]&&row-i+direction[j][0]<17&&0<=col+direction[j][1]&&col+direction[j][1]<17&&curGrids[row-i+direction[j][0]][col+direction[j][1]]==0){
                        temLocation[mayAddscore]=new int[] {row-i+direction[j][0],col+direction[j][1]};
                        mayAddscore+=1;
                    }
                }
            }else{
                break;
            }
        }
        direction = new int[][] {{1,-1},{1,0},{1,1}};
        for (int i = 1;i<=right;i++){
            if (curGrids[row+i][col] == value){
                formationCount++;
                for (int j =0;j<3;j++){
                    if (0<=row+i+direction[j][0]&&row+i+direction[j][0]<17&&0<=col+direction[j][1]&&col+direction[j][1]<17&&curGrids[row+i+direction[j][0]][col+direction[j][1]]==0){
                        temLocation[mayAddscore]=new int[] {row+i+direction[j][0],col+direction[j][1]};
                        mayAddscore+=1;
                    }
                }
            }else{
                break;
            }
        }
        if (formationCount >= consecutiveNumber) {
            if (value==1){
                for (int i=0;i<mayAddscore;i++){
                    for (int j=0;j<blackScore/10;j++){
                        if (blackScoreLocation[j][0]==temLocation[i][0] && blackScoreLocation[j][1]==temLocation[i][1]){
                            flag2=1;
                            break;
                        }
                    }
                    if (flag2==1){
                        flag2=0;
                        continue;
                    }
                    blackScoreLocation[blackScore/10][0]=temLocation[i][0];
                    blackScoreLocation[blackScore/10][1]=temLocation[i][1];
                    blackScore+=10;
                    if (blackScore==100){
                        doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "执黑棋，战胜" + player_white.getNickNameOrTemp());
                        return 1;
                    }
                }
            }
            else{
                for (int i=0;i<mayAddscore;i++){
                    for (int j=0;j<(whiteScore-5)/10;j++){
                        if (whiteScoreLocation[j][0]==temLocation[i][0] && whiteScoreLocation[j][1]==temLocation[i][1]){
                            flag2=1;
                            break;
                        }
                    }
                    if (flag2==1){
                        flag2=0;
                        continue;
                    }
                    whiteScoreLocation[(whiteScore-5)/10][0]=temLocation[i][0];
                    whiteScoreLocation[(whiteScore-5)/10][1]=temLocation[i][1];
                    whiteScore+=10;
                    if (whiteScore>=100){
                        doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "执白棋，战胜" + player_black.getNickNameOrTemp());
                        return 1;
                    }
                }
            }
        }
        mayAddscore=0;
        direction =new int[][] {{-1, 1}, {-1, 0}, {-1, -1}, {0, 1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}};

        for (int j =0;j<8;j++) {
            if (0 <= row + direction[j][0] && row + direction[j][0] < 17 && 0 <= col + direction[j][1] && col + direction[j][1] < 17 && curGrids[row + direction[j][0]][col + direction[j][1]] == 0) {
                mayAddscore += 1;
            }
        }
        if (value==1){blackScore+=10*mayAddscore;}
        else{whiteScore+=10*mayAddscore;}
        if (blackScore>=100 || whiteScore>=100){
            if (value == 1) {
                doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "执黑棋，战胜" + player_white.getNickNameOrTemp());
            } else {
                doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "执白棋，战胜" + player_black.getNickNameOrTemp());
            }
        }
        return 0;

    }

}